<!-- components/uni-echart/uni-echart.vue -->
<template>
  <view class="chart-container">
    <!-- #ifdef APP-PLUS || H5 -->
    <view 
      :id="chartId"
      :prop="mergedOption"
      :change:prop="echarts.updateEcharts"
      @click="handleChartClick"
      class="echarts-canvas"
    />
    <!-- #endif -->
    <!-- #ifndef APP-PLUS || H5 -->
    <slot name="fallback">
      <view class="unsupported-tip">当前环境不支持图表渲染</view>
    </slot>
    <!-- #endif -->
  </view>
</template>

<script>
import { ref, watch, onMounted, onBeforeUnmount } from 'vue'

export default {
  name: 'UniEchart',
  props: {
    option: {
      type: Object,
      required: true
    },
    theme: {
      type: String,
      default: 'light',
      validator: (v) => ['light', 'dark'].includes(v)
    },
    chartId: {
      type: String,
      default: () => `chart_${Math.random().toString(36).substr(2, 9)}`
    },
    resizeDelay: {
      type: Number,
      default: 300
    }
  },

  setup(props, { emit, expose }) {
    const mergedOption = ref({})
    let resizeObserver = null

    // 响应式处理配置项
    watch(() => props.option, (newVal) => {
      mergedOption.value = {
        ...newVal,
        backgroundColor: props.theme === 'dark' ? '#2c3e50' : '#fff'
      }
    }, { immediate: true, deep: true })

    // 生命周期处理
    onMounted(() => {
      initResizeObserver()
    })

    onBeforeUnmount(() => {
      resizeObserver?.disconnect()
    })

    // 初始化ResizeObserver
    const initResizeObserver = () => {
      if (typeof ResizeObserver === 'function') {
        resizeObserver = new ResizeObserver(entries => {
          emit('chartResize', entries[0].contentRect)
          debouncedResize()
        })
        // #ifdef H5
        const container = document.getElementById(props.chartId)
        container && resizeObserver.observe(container)
        // #endif
      }
    }

    // 防抖处理
    const debouncedResize = debounce(() => {
      emit('chartResized')
    }, props.resizeDelay)

    // 暴露方法
    expose({
      getOption: () => mergedOption.value,
      updateTheme: (newTheme) => {
        mergedOption.value.backgroundColor = newTheme === 'dark' ? '#2c3e50' : '#fff'
      }
    })

    return {
      mergedOption,
      handleChartClick: (event) => {
        emit('chartClick', normalizeEvent(event))
      }
    }
  }
}

// 工具函数
function debounce(func, wait) {
  let timeout
  return function(...args) {
    clearTimeout(timeout)
    timeout = setTimeout(() => {
      func.apply(this, args)
    }, wait)
  }
}

function normalizeEvent(event) {
  return uni.getSystemInfoSync().platform === 'h5' ? 
    { ...event, touches: [event] } : 
    event
}
</script>

<script module="echarts" lang="renderjs">
let myChart = null
let echartsLoader = null
let isEchartsLoaded = false
export default {
  mounted() {
    this.initEcharts()
  },
  methods: {
     async initEcharts() {
	    if (!isEchartsLoaded && !window.echarts) {
		     await this.loadStaticEcharts()
		     isEchartsLoaded = true
		   }
       // 静态资源加载逻辑
       if (!window.echarts) {
         await this.loadStaticEcharts()
       }
       
       try {
         myChart = echarts.init(document.getElementById(this.chartId))
         myChart.setOption(this.mergedOption)
         this.bindEvents()
         this.$ownerInstance.callMethod('onChartReady')
       } catch (error) {
         console.error('ECharts初始化失败:', error)
       }
     },
     
     loadStaticEcharts() {
       return new Promise((resolve, reject) => {
         const script = document.createElement('script')
         script.src = '/static/echarts.min.js'
         script.onload = resolve
         script.onerror = reject
         document.head.appendChild(script)
       })
     },

    updateEcharts(newOption) {
      if (myChart && newOption) {
        myChart.setOption(newOption, {
          notMerge: true,
          lazyUpdate: true
        })
        myChart.resize()
      }
    },

    bindEvents() {
      myChart.getZr().on('click', params => {
        const pointInPixel = [params.offsetX, params.offsetY]
        const pointInGrid = myChart.convertFromPixel('grid', pointInPixel)
        this.$ownerInstance.callMethod('handleChartClick', {
          pixel: pointInPixel,
          data: pointInGrid
        })
      })
    }
  }
}
</script>

<style scoped>
.chart-container {
  position: relative;
  width: 100%;
  height: 100%;
}

.echarts-canvas {
  width: 100%;
  height: 100%;
  min-height: 300px;
}

.unsupported-tip {
  padding: 20rpx;
  color: #999;
  text-align: center;
  border: 1px dashed #eee;
}
</style>